App.require(function () {
    var app = App.getCurrent();

    app.definePage("strdateRangePickerActive", {
        getDomObj: function () {
            this.attachDom(".select-range-main-container", "mainContainer")
                .attachDom(".select-range-container", "selectContainer")
                .attachDiyEvent("changeState", this.changeStateHandler)
                .attachEvent("mainContainer", "touchstart", this.touchstartHandler, false)
                .attachEvent("mainContainer", "touchmove", this.touchmoveHandler, false)
                .attachEvent("mainContainer", "touchend", this.touchendHandler, false)
                .attachEvent("selectContainer", "click", this.selectHandler, false);
        },
        touchstartHandler: function (ev) {
            var touches = ev.touches;
            if (touches.length > 1) return;
            var touch = touches[0];
            this.data.startY = touch.clientY;
            this.data.startTime = Date.now();
            this.data.backTransformY = this.data.transformY;
        },
        touchmoveHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            var touches = ev.touches;
            if (touches.length > 1) return;
            var moveY = touches[0].clientY;
            var deltaY = this.data.startY - moveY;
            this.changeYearContainer(deltaY);
        },
        touchendHandler: function (ev) {
            var touches = ev.changedTouches;
            if (touches.length > 1) return;
            this.data.transformY = this.data.backTransformY;
        },
        changeYearContainer: function (deltaY) {
            var transformY = this.data.transformY - deltaY, data = this.data,
                selectContainer = this.domList.selectContainer,
                mainContainer = this.domList.mainContainer,
                maxHeight = data.prevHeight + data.nowHeight + data.nextHeight + 3 * 48 - mainContainer.clientHeight;
            
            var now = new Date(),
                tYear = now.getFullYear(),
                tMonth = now.getMonth() + 1,
                tDay = now.getDate(),
                data = this.data,
                baseDate = data.baseDate, 
                startYDate = data.startYDate,
                endYDate = data.endYDate;

            if (transformY > 0) {
                var preObj = this._computeHTML(baseDate.previousMonth().previousMonth(), startYDate, endYDate, tYear, tMonth, tDay);
                baseDate.nextMonth();

                selectContainer.removeChild(selectContainer.lastElementChild);
                var div = document.createElement("div");
                div.innerHTML = preObj.html;
                selectContainer.insertBefore(div, selectContainer.firstElementChild);
                this._initContainer();
                data.nextHeight = data.nowHeight;
                data.nowHeight = data.prevHeight;
                data.prevHeight = preObj.height;
                transformY -= preObj.height + 48;
                this.data.startY += preObj.height + 48;
                this.addStyle();
            }
            else if (transformY < -maxHeight) {
                var nextObj = this._computeHTML(baseDate.nextMonth().nextMonth(), startYDate, endYDate, tYear, tMonth, tDay);
                baseDate.previousMonth();

                selectContainer.removeChild(selectContainer.firstElementChild);
                var div = document.createElement("div");
                div.innerHTML = nextObj.html;
                selectContainer.appendChild(div);
                this._initContainer();


                transformY += data.prevHeight + 48;
                this.data.startY -= data.prevHeight + 48;

                data.prevHeight = data.nowHeight;
                data.nowHeight = data.nextHeight;
                data.nextHeight = nextObj.height;
                this.addStyle();
            }
            selectContainer.style.transform = "translateY(" + transformY + "px)";
            
            this.data.backTransformY = transformY;
        },
        changeStateHandler: function (ev) {
            this.data.changeState = ev.state;
        },
        selectHandler: function (ev) {
            var target = ev.target, data = this.data, container = this.domList.selectContainer;
            var li = Component.getNodeName(target, "LI");
            if (li && li.classList.contains("str-disabled-date-item")) return false;
            if (target.nodeName.toUpperCase() === "SPAN") {
                if (!target.textContent) return;
                var day = parseInt(target.textContent),
                    li = target.parentNode,
                    div = li.parentNode.parentNode,
                    str = div.dataset.str, year, month, date = data.baseDate;

                if (str === "previous") {
                    date.previousMonth();
                    year = date.year;
                    month = date.month;
                    date.nextMonth();
                }
                else if (str === "current") {
                    year = date.year;
                    month = date.month;
                }
                else if (str === "next") {
                    date.nextMonth();
                    year = date.year;
                    month = date.month;
                    date.previousMonth();
                }
                if (data.state === 0) {
                    data.startYDate.set(year, month, day);
                    this.setStartDate();
                    target.parentNode.classList.add("selected");
                    if (data.endYDate.year) {
                        data.state = 2;
                        this.addStyle();
                    }
                    else data.state = 1;
                    
                    
                }
                else if (data.state === 1) {
                    if (data.startYDate.compare(year, month, day) > 0) {
                        data.startYDate.clone(data.endYDate);
                        data.startYDate.set(year, month, day);
                    }
                    else {
                        data.endYDate.set(year, month, day);
                    }
                    target.parentNode.classList.add("selected");
                    data.state = 2;
                    this.addStyle();
                    this.setStartDate();
                    this.setEndDate();
                }
                else if (data.state === 2) {
                    
                    if (data.changeState === 0) {
                        var firstLi = this.getFirstSelectLi(container);
                        if (firstLi && data.startYDate.compare(data.endYDate.year, data.endYDate.month, data.endYDate.day) !== 0) firstLi.classList.remove("selected");
                        if (data.endYDate.compare(year, month, day) < 0) {
                            data.endYDate.clone(data.startYDate);
                            data.endYDate.set(year, month, day);
                        }
                        else {
                            if (data.startYDate.compare(year, month, day) !== 0) {
                                data.startYDate.set(year, month, day);
                            }
                        }
                        var lastLi = this.getLastSelectLi(container);
                        if (data.startYDate.compare(data.endYDate.year, data.endYDate.month, data.endYDate.day) === 0) {
                            if (lastLi) lastLi.classList.remove("select-area-end");
                            if (firstLi) firstLi.classList.remove("select-area-begin");
                        }
                        else {
                            if (lastLi) lastLi.classList.add("select-area-end");
                            if (firstLi) firstLi.classList.add("select-area-begin");
                        }
                    }
                    else {
                        var lastLi = this.getLastSelectLi(container);
                        if (lastLi && data.startYDate.compare(data.endYDate.year, data.endYDate.month, data.endYDate.day) !== 0) {
                            lastLi.classList.remove("selected");
                            lastLi.classList.remove("select-area-end");
                        }
                        
                        if (data.startYDate.compare(year, month, day) > 0) {
                            data.startYDate.clone(data.endYDate);
                            data.startYDate.set(year, month, day);
                        }
                        else {
                            if (data.endYDate.compare(year, month, day) !== 0) {
                                data.endYDate.set(year, month, day);
                            }
                        }
                        var firstLi = this.getFirstSelectLi(container);
                        if (data.startYDate.compare(data.endYDate.year, data.endYDate.month, data.endYDate.day) === 0) {
                            if (firstLi) firstLi.classList.remove("select-area-begin");
                        }
                        else {
                            if (lastLi) lastLi.classList.add("select-area-end");
                            if (firstLi) firstLi.classList.add("select-area-begin");
                        }
                    }
                    target.parentNode.classList.add("selected");
                    this.addStyle();
                    this.setStartDate();
                    this.setEndDate();
                }
            }
        },
        getFirstSelectLi: function (container) {
            var data = this.data, baseDate = data.baseDate, startYDate = data.startYDate, li = null;
            baseDate.previousMonth();
            if (startYDate.compare(baseDate.year, baseDate.month, baseDate.day) >= 0)  {
                li = container.querySelector(".selected");
            }
            baseDate.nextMonth();
            return li;
        },
        getLastSelectLi: function (container) {
            var data = this.data, baseDate = data.baseDate, endYDate = data.endYDate, li = null;
            baseDate.nextMonth().nextMonth();
            if (endYDate.compare(baseDate.year, baseDate.month, baseDate.day) < 0)  {
                var lis = container.querySelectorAll(".selected");
                if (lis.length > 0) li = lis[lis.length - 1];
            }
            baseDate.previousMonth().previousMonth();
            return li;
        },
        addStyle: function () {
            var data = this.data,
                baseDate = data.baseDate;
                startYDate = data.startYDate,
                endYDate = data.endYDate;

            if (startYDate.year == endYDate.year && startYDate.month === endYDate.month && 
                startYDate.day === endYDate.day) {
                
                return true;
            }

            if (baseDate.year && startYDate.year && endYDate.year) {
                var prevDate = baseDate.previousMonth().clone(),
                    nextDate = baseDate.nextMonth().nextMonth().clone(),
                    lastDate = nextDate.nextMonth().previousDay().clone(),
                    selectContainer = this.domList.selectContainer,
                    children = this.domList.selectContainer.children;
                
                var beginAreas = selectContainer.querySelectorAll(".select-area-begin"),
                    endAreas = selectContainer.querySelectorAll(".select-area-end");
                for (var i = 0; i < beginAreas.length; i++) beginAreas[i].classList.remove("select-area-begin");
                for (var i = 0; i < endAreas.length; i++) endAreas[i].classList.remove("select-area-end");
                baseDate.previousMonth();
                nextDate.nextDay().previousMonth();
                if (startYDate.compare(prevDate) < 0) {
                    if (endYDate.compare(prevDate) > 0) this.setAreaBegin(children[0]);
                    if (endYDate.compare(baseDate) > 0) this.setAreaBegin(children[1]);
                    if (endYDate.compare(nextDate) > 0) this.setAreaBegin(children[2]);
                    var selected = selectContainer.querySelector(".selected");
                    if (selected) selected.classList.add("select-area-end");
                }
                else if (startYDate.compare(lastDate) < 0) {
                    var selecteds = selectContainer.querySelectorAll(".selected");
                    if (selecteds[0]) selecteds[0].classList.add("select-area-begin");
                    if (endYDate.compare(lastDate) < 0) {
                        if (selecteds[1]) selecteds[1].classList.add("select-area-end");
                    }
                    if (baseDate.compare(startYDate) > 0 && baseDate.compare(endYDate) < 0) {
                        this.setAreaBegin(children[1]);
                    }
                    if (nextDate.compare(startYDate) > 0 && nextDate.compare(endYDate) < 0) {
                        this.setAreaBegin(children[2]);
                    }
                }
            }
        },
        setAreaBegin: function (dom) {
            if (dom) dom.querySelector(".date-item").classList.add("select-area-begin");
        },
        setStartDate: function () {
            this.parent.staticPage.dispatchEvent({ type: "changeDate", sign: 0, string: this.data.startYDate.toMonthDay() });
        },
        setEndDate: function () {
            this.parent.staticPage.dispatchEvent({ type: "changeDate", sign: 1, string: this.data.endYDate.toMonthDay() });
        },
        _initContainer: function () {
            var children = this.domList.selectContainer.children;
            children[0].dataset.str = "previous";
            children[1].dataset.str = "current";
            children[2].dataset.str = "next";
            this.prevContainer = children[0];
            this.nowContainer = children[1];
            this.nextContainer = children[2];
        },
        init: function () {
            this.data.changeState = 1; // 0代表start, 1代表end
            if (document.activeElement) document.activeElement.blur();
            var domList = this.domList,
                mainContainer = domList.mainContainer,
                container = mainContainer.firstElementChild;

            var outHeight = mainContainer.clientHeight,
                inHeight = container.clientHeight,
                transformY = -inHeight / 2 + outHeight / 2;

            container.style.transform = "translateY(" + transformY + "px)";
            this.data.transformY = transformY;
            this._initContainer();

            if (this.data.state == 2) {
                this.addStyle();
            }
        },
        computeHtml: function (yDate, startYDate, endYDate) {
            var data = this.data,
                now = new Date(),
                tYear = now.getFullYear(),
                tMonth = now.getMonth() + 1,
                tDay = now.getDate();

            var nowObj = this._computeHTML(yDate, startYDate, endYDate, tYear, tMonth, tDay),
                prevObj = this._computeHTML(yDate.previousMonth(), startYDate, endYDate, tYear, tMonth, tDay),
                nextObj = this._computeHTML(yDate.nextMonth().nextMonth(), startYDate, endYDate, tYear, tMonth, tDay);
            data.nowHTML = nowObj.html;
            data.nowHeight = nowObj.height;
            data.prevHTML = prevObj.html;
            data.prevHeight = prevObj.height;
            data.nextHTML = nextObj.html;
            data.nextHeight = nextObj.height;
            yDate.previousMonth();
        },
        _computeHTML: function (currentYDate, startYDate, endYDate, tYear, tMonth, tDay) {
            var obj = currentYDate.getMonthDays(),
                year = currentYDate.year,
                month = currentYDate.month,
                total, height,
                titleStr = currentYDate.toYearMonth(),
                html = '<h3>' + titleStr + '</h3><ul>';

            for (var i = 0; i < obj.prevNum; i++) {
                html += "<li><span></span></li>";
            }
            for (var i = 0; i < obj.num; i++) {
                var additionClass = this.computeIsDisabled(year, month, i + 1);
                if ((year == startYDate.year && month == startYDate.month && i == startYDate.day - 1) ||
                    (year == endYDate.year && month == endYDate.month && i == endYDate.day - 1)) {
                    html += "<li class='date-item selected " + additionClass + "'><span>" + (i + 1) + "</span></li>";
                } else if (tYear == year && tMonth == month && tDay - 1 == i) {
                    html += "<li class='date-item now " + additionClass + "'><span>" + (i + 1) + "</span></li>";
                } else {
                    html += "<li class='date-item " + additionClass + "'><span>" + (i + 1) + "</span></li>";
                }
            }
            html += '</ul>';
            total = obj.prevNum + obj.num;
            if (parseInt(total / 7) == Math.ceil(total / 7)) height = parseInt(total / 7) * 48;
            else height = parseInt(total / 7 + 1) * 48;
            return {
                html: html, 
                height: height
            };
        },
        computeIsDisabled: function (year, month, day) {
            var minDate = this.data.minDate, maxDate = this.data.maxDate;
            if (!minDate.year && !maxDate.year) return "";

            if (!minDate.year) {
                if (maxDate.compare(year, month, day) > -1) return "";
                return " str-disabled-date-item";
            }
            if (!maxDate.year) {
                if (minDate.compare(year, month, day) < 1) return "";
                return " str-disabled-date-item";
            }

            if (maxDate.compare(year, month, day) > -1 && minDate.compare(year, month, day) < 1) return "";
            return " str-disabled-date-item";
        },
        render: function (next) {
            var data = this.data,
                pData = this.parent.data;
            data.startYDate = pData.startYDate;
            data.endYDate = pData.endYDate;
            data.minDate = pData.minDate;
            data.maxDate = pData.maxDate;
            if (data.startYDate.year) {
                data.baseDate = data.startYDate.clone();
                this.computeHtml(data.baseDate, data.startYDate, data.endYDate);

            } else if (data.endYDate.year) {
                data.baseDate = data.endYDate.clone();
                this.computeHtml(data.baseDate, data.startYDate, data.endYDate);
            } else {
                data.baseDate = data.startYDate.constructor.fromNow();
                this.computeHtml(data.baseDate, data.startYDate, data.endYDate)
            }
            data.baseDate.day = 1;

            this.data.state = 0; // 0代表没有输入, 1代表输入一个时间， 2代表输入两个时间
            if (this.data.startYDate.year && this.data.endYDate.year) this.data.state = 2;
            else if (this.data.startYDate.year) this.data.state = 1;

            this.fetch("./index.html", function (html) {
                next(this.renderHTML(html));
            })
        }
    })
});